#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <malloc.h>
#include <string.h>

#include "getch.h"
#include "game_function.h"
#include "show.h"
#include "login.h"

struct core *init()
{
    struct core *p_core = NULL;
    p_core = (struct core *)malloc(sizeof(struct core));

    p_core->data = read_file();

    p_core->pattern[0] = NULL;
    p_core->pattern[1] = NULL;
    p_core->pattern[2] = NULL;
    p_core->pattern[3] = NULL;

    return p_core;
}

int run(struct core *p_core)
{
    char *name = NULL;
    int check = BACK;

    while (check == BACK) {
        /*主菜单按下退出游戏键返回值为NULL */
        if((name = menu_show(p_core->data)) == NULL)
            return 0;

        check = game(p_core, name);
    }

    return 0;
}

void destory(struct core *core)
{
    struct data *p_data = core->data;
    struct data *temp;

    if (!core) {
        printf("ERROR");
        return;
    }

    write_to_file(core->data);
    
    while (p_data != NULL) {
        temp = p_data;
        p_data = p_data->next;
        free(temp);
    }

    free(core);
    system("clear");
}

/*
 *@brief        登陆成功后进入游戏界面
 */
int game(struct core *core, char *name)
{
    struct data *head;
    int choice;

    head = find_name(name, core->data);
    game_show();

    while (1) {   
        change_gold_grade(head->gold, head->grade);
        choice = game_choice();

        switch (choice) {
            case START_GAME:
                game_start(core, head);
                break;

            case BUY_GOLD:
                purchase_gold(head);
                break;

            case BACK:
                write_to_file(core->data);
                return BACK;

            case EXIT:
                return EXIT;

            default:    
                break;
        }
    }

    return 0;
}


int game_start(struct core *p_core, struct data *p_data)
{
    int put_gold ;

    if ((put_gold = input_gold(p_data->gold)) == 0)
        return 0;

    /*实现滚动，并取出中间一行的三个字符 */
    p_core->pattern[0] = pattern_one();
    p_core->pattern[1] = pattern_two();
    p_core->pattern[2] = pattern_three();

    /*按照图案改变积分和金币数 */
    if (p_core->pattern[0] == p_core->pattern[1] 
        && p_core->pattern[2] == p_core->pattern[0]) {
        p_data->gold = p_data->gold + put_gold *3;
        p_data->grade = p_data->grade + 15;
    } else if (p_core->pattern[0] != p_core->pattern[1] 
               && p_core->pattern[1] != p_core->pattern[2] 
               && p_core->pattern[0] != p_core->pattern[2]) {
    	p_data->gold = p_data->gold - put_gold;
        p_data->grade = p_data->grade + 1;
    } else {
    	p_data->gold = p_data->gold + put_gold * 2;
        p_data->grade = p_data->grade + 5;
    }
        
    return 0;

}

struct data *find_name(char *name, struct data *p_data)
{ 
    while (p_data != NULL) {
        if(strcmp(p_data->name, name) == 0)
            return p_data;
        
        p_data = p_data->next;
    }

    return NULL;
}

/*
 *@brief        输入投注金币量
 */
int input_gold(int gold)
{
    int put_gold;

    if (gold == 0) {
        cover();
        MOVETO(18, 10);
        printf("金币数为零,可以购买金币...\n");
        MOVETO(19, 10);
        printf("按任意键返回...\n");

        return 0;
    }

    SHOW_CURSOR();

    cover();
    MOVETO(19, 10);
    printf("请输入投注金币：");

    while (1) {
        put_gold = judge_number(0);

        if (put_gold == 0) {
            break;
        } else if (put_gold > gold || put_gold < 0) {
            cover();
            MOVETO(18, 10);
            printf("超出拥有的金币数...\n");
            MOVETO(19, 10);
            printf("请输入投注金币：");
            while (getchar() != '\n');
        } else {
            break;
        }
    }     

    HIDE_CURSOR();

    return put_gold;
}

/*
 *@brief        用积分购买金币
 */
int purchase_gold(struct data *p_data)
{
    int buy_gold;

    if (p_data->grade == 0) {
        cover();
        MOVETO(18, 10);
        printf("积分数为零...\n");
        MOVETO(19, 10);
        printf("按任意键返回...\n");

        return 0;
    }

    SHOW_CURSOR();

    cover();
    MOVETO(18, 10);
    printf("请输入购买金币数:");

    while (1) {
        buy_gold = judge_number(0);

        if (buy_gold == 0) {
            break;
        } else if (buy_gold > p_data->grade || buy_gold < 0) {
        	cover();
            MOVETO(18, 10);
            printf("超出拥有的积分数...\n");
            MOVETO(19, 10);
            printf("请输入购买金币数：");
            while (getchar() != '\n');
        } else {
        	break;
        }         
    }

    p_data->gold = p_data->gold + buy_gold;
    p_data->grade = p_data->grade - buy_gold;

    HIDE_CURSOR();

    return 0;
}

/*
 *@brief        实现滚动效果
 *@return       返回中间一行第一个字符的指针
 */
char *pattern_one(void)
{
    char *pattern[9] = {"▲ ", "⑦ ", "■ ", "▢ ", "♧ ", "◉ ", "✘ ", "★ ", "※ "};
    char *pattern_random[9];
    int cycle_num, random_num;
    time_t start, current;

    srand(time(NULL));
    time(&start);

    while (1) {
        time(&current);
        for (cycle_num = 0; cycle_num < 9; cycle_num++) {
            random_num = rand() % 9;
            pattern_random[cycle_num] = pattern[random_num];
        }
        
        MOVETO(10, 22);
        printf("%s\t\t\b\b\b%s\t\t\b\b\b%s", pattern_random[0],
                                             pattern_random[1],
                                             pattern_random[2]);
        MOVETO(11, 22);
        printf("%s\t\t\b\b\b%s\t\t\b\b\b%s", pattern_random[3],
                                             pattern_random[4],
                                             pattern_random[5]);
        MOVETO(12, 22);
        printf("%s\t\t\b\b\b%s\t\t\b\b\b%s", pattern_random[6],
                                             pattern_random[7],
                                             pattern_random[8]);
        fflush(stdout);
        usleep(70000);

        if ((current - start) == 3) {
            break;
        }
    }

    MOVETO(10, 22);
    printf("%s", pattern_random[0]);
    MOVETO(11, 22);
    printf("%s", pattern_random[1]);
    MOVETO(12, 22);
    printf("%s", pattern_random[2]);
    fflush(stdout);

    return pattern_random[1];
}

/*
 *@brief        实现滚动效果
 *@return       返回中间一行第二个字符的指针
 */
char *pattern_two(void)
{
    char *pattern[9] = {"▲ ", "⑦ ", "■ ", "▢ ", "♧ ", "◉ ", "✘ ", "★ ", "※ "};
    char *pattern_random[6];
    int cycle_num, random_num;
    time_t start, current;

    srand(time(NULL));
    time(&start);

    while (1) {
        time(&current);
        for (cycle_num = 0; cycle_num < 6; cycle_num++) {
            random_num = rand() % 9;
            pattern_random[cycle_num] = pattern[random_num];
        }
        
        MOVETO(10, 30);
        printf("%s\t\t\b\b\b%s", pattern_random[0], pattern_random[1]);
        MOVETO(11, 30);
        printf("%s\t\t\b\b\b%s", pattern_random[2], pattern_random[3]);
        MOVETO(12, 30);
        printf("%s\t\t\b\b\b%s", pattern_random[4], pattern_random[5]);
        fflush(stdout);
        usleep(70000);

        if ((current - start) == 1) {
            break;
        }
    }

    MOVETO(10, 30);
    printf("%s", pattern_random[0]);
    MOVETO(11, 30);
    printf("%s", pattern_random[1]);
    MOVETO(12, 30);
    printf("%s", pattern_random[2]);
    fflush(stdout);

    return pattern_random[1];
}

/*
 *@brief        实现滚动效果
 *@return       返回中间一行第三个字符的指针
 */
char *pattern_three(void)
{
    char *pattern[9] = {"▲ ", "⑦ ", "■ ", "▢ ", "♧ ", "◉ ", "✘ ", "★ ", "※ "};
    char *pattern_random[3];
    int cycle_num, random_num;
    time_t start, current;

    srand(time(NULL));
    time(&start);

    while (1) {
        time(&current);
        for (cycle_num = 0; cycle_num < 3; cycle_num++) {
            random_num = rand() % 9;
            pattern_random[cycle_num] = pattern[random_num];
        }
        
        MOVETO(10, 38);
        printf("%s", pattern_random[0]);
        MOVETO(11, 38);
        printf("%s", pattern_random[1]);
        MOVETO(12, 38);
        printf("%s", pattern_random[2]);
        fflush(stdout);
        usleep(70000);

        if ((current - start) == 1) {
            break;
        }
    }

    MOVETO(10, 38);
    printf("%s", pattern_random[0]);
    MOVETO(11, 38);
    printf("%s", pattern_random[1]);
    MOVETO(12, 38);
    printf("%s", pattern_random[2]);
    fflush(stdout);

    return pattern_random[1];
}

int game_choice(void)
{
    int row = 0;
    char ch;

    while ((ch = getch()) != ENTER) {
        switch (ch) {
            case LEFT:
            row--;
            break;

            case RIGHT:
            row++;
            break;

            default:
            break;
        }
       
        if (row > 3)
        row = 0;
        if (row < 0)
        row = 3;

        switch (row) {
            case START_GAME:
            MOVETO(18, 0);
            printf("┃\t┌───────────────────────────────────────────┐\t\t\b\b\b\b┃\n");
            MOVETO(19, 0);
            printf("┃\t│   ▶ 开始    购买金币     返回      退出   │\t\t\b\b\b\b┃\n");
            MOVETO(20, 0);
            printf("┃\t└───────────────────────────────────────────┘\t\t\b\b\b\b┃\n");
            break;

            case BUY_GOLD:
            MOVETO(18, 0);
            printf("┃\t┌───────────────────────────────────────────┐\t\t\b\b\b\b┃\n");
            MOVETO(19, 0);
            printf("┃\t│     开始  ▶ 购买金币     返回      退出   │\t\t\b\b\b\b┃\n");
            MOVETO(20, 0);
            printf("┃\t└───────────────────────────────────────────┘\t\t\b\b\b\b┃\n");
            break;

            case BACK:
            MOVETO(18, 0);
            printf("┃\t┌───────────────────────────────────────────┐\t\t\b\b\b\b┃\n");
            MOVETO(19, 0);
            printf("┃\t│     开始    购买金币   ▶ 返回      退出   │\t\t\b\b\b\b┃\n");
            MOVETO(20, 0); 
            printf("┃\t└───────────────────────────────────────────┘\t\t\b\b\b\b┃\n");
            break;

            case EXIT:
            MOVETO(18, 0);
            printf("┃\t┌───────────────────────────────────────────┐\t\t\b\b\b\b┃\n");
            MOVETO(19, 0);
            printf("┃\t│     开始    购买金币     返回    ▶ 退出   │\t\t\b\b\b\b┃\n");
            MOVETO(20, 0);
            printf("┃\t└───────────────────────────────────────────┘\t\t\b\b\b\b┃\n");
            break;

            default:
            break;
        }
    }

    return row;
}

void game_show(void)
{
    system("clear");
    HIDE_CURSOR();

    printf("\n\n\n");
    printf("       ┌━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┐\n");
    printf("┌━━━━━━┃            欢迎进入老虎机游戏               ┃━━━━━━┐\n");
    printf("┃      ┃                m(=∩王∩=)m                   ┃      ┃\n");
    printf("┃      ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛      ┃\n");
    printf("┃                                                           ┃\n");
    printf("┃                █████████████████████████                  ┃\n");
    printf("┃                ┇   ⑦   ┇   ⑦   ┇   ⑦   ┇                  ┃\n");
    printf("┃                →   ⑦   ┇   ⑦   ┇   ⑦   ←                  ┃\n");
    printf("┃                ┇   ⑦   ┇   ⑦   ┇   ⑦   ┇                  ┃\n");
    printf("┃                █████████████████████████                  ┃\n");
    printf("┃                ┃   ◈ gold              ┃                  ┃\n");
    printf("┃                ┃   ◈ grade             ┃                  ┃\n");
    printf("┃                █████████████████████████                  ┃\n");
    printf("┃                                                           ┃\n");
    printf("┃       ┌───────────────────────────────────────────┐       ┃\n");
    printf("┃       │   ▶ 开始    购买金币     返回     退出    │       ┃\n");
    printf("┃       └───────────────────────────────────────────┘       ┃\n");
    printf("┃      ┌━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┐      ┃\n");
    printf("┗━━━━━━┃           ★  ★  ★  ★  ★  ★  ★  ★            ┃━━━━━━┛\n");
    printf("       ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n");
    printf("按 ← → 键选择，Enter键确认，输入金币和购买金币按 0 可退出...");
}

/*
 *@brief        改变积分数和金币数
 */
void change_gold_grade(int gold, int grade)
{
    MOVETO(14, 33);
    printf("      ");
    MOVETO(14, 33);
    printf("%d", gold);

    MOVETO(15, 33);
    printf("      ");
    MOVETO(15, 33);
    printf("%d\n\n\n", grade);
    fflush(stdout);
}

void cover(void)
{
    MOVETO(18, 0);
    printf("┃                                                           ┃\n");
    MOVETO(19, 0);
    printf("┃                                                           ┃\n");
    MOVETO(20, 0);
    printf("┃                                                           ┃\n");
}

/*
 *@brief        检测猜数字输入的字符是否为纯数字
 *@return       用户输入的纯数字
 */
int judge_number(int first_input_number)
{
	int count;
	int ret = 1;
	int length = 0;
	char change_input_number[30];
		    
	while (1) {
		scanf("%s",change_input_number);
		       
		length = strlen(change_input_number);
			   
		for (count = 0; count < length; count++) {
			if (change_input_number[count] >= '0' && change_input_number[count] <= '9') {
				ret = 1;
				continue;
			} 
			else {
				cover();
                MOVETO(18, 10);
                printf("输入有误，请输入数字...\n");
                MOVETO(19, 10);
                printf("请重新输入:");
				ret = 0;
				break;
			}
		}
		
		if (ret == 0) {
			continue;
		}
		
		first_input_number = atoi(change_input_number);
		break;
	}
	
	return first_input_number;
}

void rank(struct data *p_data) 
{
    struct data *temp;
    int data_num = 0;
    int temp_gold, temp_grade;
    char temp_name[20], temp_passwd[20];

    temp = p_data;
    /*计算链表节点数 */
    while (temp) {
        data_num++;
        temp = temp->next;
    }

    temp = p_data;

    /*链表排序 */
    while ((data_num - 1) > 0) {
        while (temp->next) {
            if (temp->grade < temp->next->grade) {
               strcpy(temp_name, temp->next->name);
               strcpy(temp->next->name, temp->name);
               strcpy(temp->name, temp_name);

               strcpy(temp_passwd, temp->next->passwd);
               strcpy(temp->next->passwd, temp->passwd);
               strcpy(temp->passwd, temp_passwd);

                temp_grade = temp->next->grade;
                temp->next->grade = temp->grade;
                temp->grade = temp_grade;

                temp_gold = temp->next->gold;
                temp->next->gold = temp->gold;
                temp->gold = temp_gold;
            } 
            temp = temp->next;
        }
        temp = p_data;
        data_num--;
    }

    temp = p_data;

    printf("\t用户名\t\t▍积分\t\t▍金币\n");
    while (temp) {
        printf("\t%s\t\t▍%d\t\t▍%d\n", temp->name, temp->grade, temp->gold);
        temp = temp->next;
    }
    
    printf("\t按任意键退出...");
}
